import pandas as pd
import os, json
from pymongo import MongoClient
from tools9 import calculate_rest_car_count,time_to_minutes,calculate_load_time,calculate_start_time,plan_to_result
from aluminum_roll9 import generate_a_schedule,assign_discard_aluminum_tasks,assign_changsha_aluminum_roll_tasks
from aluminum_rod9 import assign_early_aluminum_rod_tasks,assign_late_aluminum_rod_tasks
from mongo_database9 import update_mongodb
from double_zero9 import double_zero_tasks
from single_top9 import single_top_tasks_morning,single_top_tasks_afternoon
from al_rool_morning9 import al_rool_morning
from jieche_changde9 import jieche_changde_tasks


# ----------------------
# 定义今日运输任务需求
# ----------------------

plan_file = 'parsed_plan.json'
if not os.path.exists(plan_file):
    raise FileNotFoundError("未找到 parsed_plan.json。请先运行 input.py 生成该文件。")

with open(plan_file, 'r', encoding='utf-8') as f:
    payload = json.load(f)

cargo = payload.get('cargo', {})
staff = payload.get('staff', {})


# 将 input.py 的结构映射到 today_tasks
today_tasks = {
    '铝卷': {
        'count': cargo.get('铝卷', {}).get('count'),
        'discard_drop_count': 1,
        'discard_count':1,
    },
    '铝棒': {
        'times': cargo.get('铝棒', {}).get('load_times')
    },
    '单顶': {
        'times': cargo.get('单顶', {}).get('load_times')
    },
    '双零箔': {
        'count': cargo.get('双零箔', {}).get('count'),
        'four_point_two': cargo.get('双零箔', {}).get('size_breakdown', {}).get('four_point_two'),
        'ten_point_five': cargo.get('双零箔', {}).get('size_breakdown', {}).get('ten_point_five'),
        'thirteen': cargo.get('双零箔', {}).get('size_breakdown', {}).get('thirteen'),
        'load_time': '7:50'
    },
    '废铝卷': {
        'count': cargo.get('废铝卷', {}).get('count'),
        'scania': cargo.get('废铝卷', {}).get('scania'),
        'benz': cargo.get('废铝卷', {}).get('benz')
    },
    '常德甩挂人员': {
        'name': staff.get('name')
    },
    '长沙甩挂人员': {
        'name': '刘锦红'
    },
    '休息人员名单': {
        'rest_names': staff.get('rest_names')
    },
    '休息车辆': {
        'rest_car_numbers': payload.get('rest_car_numbers')
    }
}

# ----------------------
# MongoDB数据加载
# ----------------------
MONGO_URI = "mongodb://172.40.10.141:27017/"
DB_NAME = "innerVehicle"
VEH_COLL = "vehicle_test"
DRV_COLL = "driver_test"
client = MongoClient(MONGO_URI)
db_update = client[DB_NAME]
collection_driver = db_update[DRV_COLL]
collection_vehicle = db_update[VEH_COLL]


# ----------------------
# 计算休息车辆数量
# ----------------------
car_count_list=calculate_rest_car_count(collection_vehicle, today_tasks['休息车辆']['rest_car_numbers'])


# ----------------------
# 初始化车辆
# ----------------------
vehicles = []
for i in range(8-int(car_count_list[0]['rest_count'])):
    vehicles.append({'id': f'S{i + 1}', 'type': 'SCANIA', 'available_time': -540, 'used': False})
for i in range(2-int(car_count_list[1]['rest_count'])):
    vehicles.append({'id': f'B{i + 1}', 'type': '奔驰', 'available_time': -540, 'used': False})
for i in range(3-int(car_count_list[2]['rest_count'])):
    vehicles.append({'id': f'J{i + 1}', 'type': '解放', 'available_time': -540, 'used': False})
van_vehicles = []
for i in range(3-int(car_count_list[3]['rest_count'])):
    van = {'id': f'X{i + 1}', 'type': '厢车', 'available_time': -540, 'used': False}
    vehicles.append(van)
    van_vehicles.append(van)


# ----------------------
# 初始化任务（不含铝卷）
# ----------------------
tasks = []
for i in range(today_tasks['废铝卷']['count']):
    if i<2:
        if i<today_tasks['废铝卷']['scania']:
            tasks.append({'type': '废铝/铝卷', 'time': '7:00', 'car_type': 'SCANIA'})
        else:
            tasks.append({'type': '废铝/铝卷', 'time': '7:00', 'car_type': '奔驰'})
    else:
        if i < today_tasks['废铝卷']['scania']:
            tasks.append({'type': '废铝/铝卷', 'time': '8:30', 'car_type': 'SCANIA'})
        else:
            tasks.append({'type': '废铝/铝卷', 'time': '8:30', 'car_type': '奔驰'})
for i in range(today_tasks['双零箔']['count']):
    if i<today_tasks['双零箔']['four_point_two']:
        tasks.append({'type': '双零箔', 'time': today_tasks['双零箔']['load_time'],'car_type': '厢车'})
    else:
        tasks.append({'type': '双零箔', 'time': today_tasks['双零箔']['load_time'], 'car_type': '解放'})
for time in today_tasks['单顶']['times']:
    tasks.append({'type': '单顶', 'time': time})
for time in today_tasks['铝棒']['times']:
    tasks.append({'type': '铝棒', 'time': time})


# ----------------------
# 货物废铝卷、双零箔、单顶、铝棒、铝卷，安排车辆
# ----------------------
schedule = []
for i in range(len(tasks)):
    task = tasks[i]
    task_time_str = task['time']
    task_time = time_to_minutes(task_time_str)
    selected = None

    if task['type'] == '废铝/铝卷':
        j_candidates = [v for v in vehicles if v['type'] == task['car_type'] and v['available_time'] + 540 <= task_time]
        selected = j_candidates[0] if j_candidates else None
        if selected:
            schedule.append({
                'driver_name': '', 'plate_number': '', 'vehicle_id': selected['id'],
                'vehicle_type': selected['type'], 'departure_time': task_time_str,
                'load_time': calculate_load_time(task_time_str,task['type']), 'cargo_type': task['type'],
                'is_transfer': '否'
            })
            selected['available_time'] = time_to_minutes('24:00')
            selected['used'] = True
        else:
            print('时间为',task['time'],'的',task['type'],'无车辆可安排')

    if task['type'] == '双零箔':
        j_candidates = [v for v in vehicles if v['type'] == task['car_type'] and v['available_time'] + 540 <= task_time]
        selected = j_candidates[0] if j_candidates else None
        if not selected:
            scania_benz = [v for v in vehicles if
                           v['type'] in ['SCANIA', '奔驰'] and v['available_time'] + 540 <= task_time]
            selected = scania_benz[0] if scania_benz else None
        if selected:
            schedule.append({
                'driver_name': '', 'plate_number': '', 'vehicle_id': selected['id'],
                'vehicle_type': selected['type'], 'departure_time': calculate_start_time(task_time_str, task['type']),
                'load_time': task_time_str, 'cargo_type': task['type'],
                'is_transfer': '否'
            })
            selected['available_time'] = time_to_minutes('24:00')
            selected['used'] = True
        else:
            print('时间为',task['time'],'的',task['type'],'无车辆可安排')

    if task['type'] in ['铝棒', '单顶']:
        j_candidates = [v for v in vehicles if v['type'] == '解放' and v['available_time'] + 540 <= task_time]
        selected = j_candidates[0] if j_candidates else None
        if not selected:
            scania_benz = [v for v in vehicles if
                           v['type'] in ['奔驰'] and v['available_time'] + 540 <= task_time]
            selected = scania_benz[0] if scania_benz else None
        if not selected:
            scania_benz = [v for v in vehicles if
                           v['type'] in ['SCANIA'] and v['available_time'] + 540 <= task_time]
            selected = scania_benz[0] if scania_benz else None
        if selected:
            schedule.append({
                'driver_name': '', 'plate_number': '', 'vehicle_id': selected['id'],
                'vehicle_type': selected['type'], 'departure_time': calculate_start_time(task_time_str,task['type']),
                'load_time': task_time_str, 'cargo_type': task['type'],
                'is_transfer': '否'
            })
            if task['type'] == '铝棒':
                selected['available_time'] = time_to_minutes(schedule[-1]['load_time'])
            else:
                selected['available_time'] = time_to_minutes('24:00')
            selected['used'] = True
        else:
            print('时间为',task['time'],'的',task['type'],'无车辆可安排')


# ----------------------
# 处理剩余铝卷任务
# ----------------------
schedule = generate_a_schedule(today_tasks, schedule, vehicles)


# ----------------------
# 更新接车状态
# ----------------------
vehicle_trips = {}
for item in schedule:
    vid = item['vehicle_id']
    vehicle_trips[vid] = vehicle_trips.get(vid, 0) + 1
for item in schedule:
    if vehicle_trips[item['vehicle_id']] >= 2:
        item['is_transfer'] = '是'


# ----------------------
# 合并所有任务并排序
# ----------------------
all_tasks = schedule
# all_tasks.sort(key=lambda x: time_to_minutes(x['departure_time']) if x['departure_time'] else float('inf'))

# ----------------------
# 转换为DataFrame并保存为CSV
# ----------------------
df = pd.DataFrame(all_tasks)
df = df[['driver_name', 'plate_number', 'vehicle_id', 'vehicle_type', 'departure_time', 'load_time', 'cargo_type',
         'is_transfer']]
df.to_csv('今日运输任务调度总表.csv', index=False, encoding='utf-8-sig')
print("已生成CSV格式的今日运输任务调度总表.csv")


# ----------------------
# MongoDB数据加载
# ----------------------
db = client[DB_NAME]
db_update = client[DB_NAME]
collection = db_update['driver_test']

update_mongodb(collection)

# 让休息人员,甩挂人员不参与后续任何任务分配
assigned_drivers = set(today_tasks['休息人员名单']['rest_names'])
assigned_vehicles = set(today_tasks['休息车辆']['rest_car_numbers'])
assigned_drivers.add(str(today_tasks['常德甩挂人员']['name']))
driver_list = today_tasks['休息车辆']['rest_car_numbers']
driver_list.append(today_tasks['常德甩挂人员']['name'])
vehicle_docs = list(db[VEH_COLL].find({}, {"_id": 0}))
driver_docs = list(db[DRV_COLL].find({}, {"_id": 0}))
vehicle_df = pd.DataFrame(vehicle_docs)
driver_df = pd.DataFrame(driver_docs)


changde_result_df,assigned_vehicles,assigned_drivers,df1 = jieche_changde_tasks(df,driver_df,vehicle_df,assigned_vehicles,assigned_drivers)
df = df[~(df["vehicle_id"].isin(df1["vehicle_id"]))]

single_top_morning_result_df,assigned_vehicles,assigned_drivers = single_top_tasks_morning(df, driver_df, vehicle_df, assigned_vehicles, assigned_drivers)
single_top_afternoon_result_df,assigned_vehicles,assigned_drivers = single_top_tasks_afternoon(df, driver_df, vehicle_df, assigned_vehicles, assigned_drivers)
double_zero_results,assigned_vehicles, assigned_drivers = double_zero_tasks(df, today_tasks, driver_df, vehicle_df, assigned_vehicles, assigned_drivers)
al_rool_morning_results, df, assigned_drivers, assigned_vehicles = al_rool_morning(df, driver_df, vehicle_df,assigned_vehicles, assigned_drivers)

early_aluminum_rod_results, assigned_drivers, assigned_vehicles, df = assign_early_aluminum_rod_tasks(df, vehicle_df, driver_df, assigned_drivers, assigned_vehicles)
discard_aluminum_results, assigned_drivers, assigned_vehicles = assign_discard_aluminum_tasks(df, vehicle_df, driver_df, assigned_drivers, assigned_vehicles)
late_aluminum_rod_results, assigned_drivers, assigned_vehicles = assign_late_aluminum_rod_tasks(df, vehicle_df, driver_df, assigned_drivers, assigned_vehicles)
changsha_aluminum_roll_results, assigned_drivers = assign_changsha_aluminum_roll_tasks(df, driver_df, assigned_drivers)
time_plan_df = pd.DataFrame(changde_result_df + single_top_morning_result_df + single_top_afternoon_result_df +
                            double_zero_results + al_rool_morning_results + early_aluminum_rod_results
                            + discard_aluminum_results + late_aluminum_rod_results + changsha_aluminum_roll_results)
result_df = plan_to_result(time_plan_df)

# print('未安排运输任务的人员名单：')
# print(assigned_drivers)
# print(driver_df[~driver_df['driver_name'].isin(assigned_drivers)]['driver_name'])
# print('未安排运输任务的车辆名单：')
# print(assigned_vehicles)
# print(vehicle_df[~vehicle_df['vehicle_id'].isin(assigned_vehicles)])
print(result_df)
result_df.to_excel('每日排班分配结果.xlsx', index=False)



